package com.lstimeline.statuschecker;

import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;

import org.htmlparser.Parser;
import org.htmlparser.filters.*;
import org.htmlparser.util.NodeList;
import org.htmlparser.util.ParserException;

import com.lstimeline.utility.Validation;

public class VirginiaLogic extends AbstractStatusChecker {
	private static final int WORD_LIMIT = 47;
	private String urlString = "https://law5.law.virginia.edu/apptrack/s/myappinfo.jsp";
 
	/**
	 * Get the jsessionid
	 */
	private void connectForCookies() {
		//jsessionid, path
		setupGETConnection(urlString);
		receiveCookies();
	}
	
	protected String getLogonString(String username, String password) throws ParserException, UnsupportedEncodingException {
		StringBuilder builder = new StringBuilder();
		queryBuilder(builder, "j_username", username);
		queryBuilder(builder, "j_password", password);
		queryBuilder(builder, "submitbutton", "Log+In");
		// remove the last '&'
		builder.deleteCharAt(builder.length() - 1);
		
		return builder.toString();
	}
	
	//AdmitWeb
	//Post logon information to j_security_check
	protected void logon(String username, String password) throws Exception{
		String logonString = getLogonString(username, password);
		urlString = "https://law5.law.virginia.edu/apptrack/j_security_check";
		// Should carry the JSESSIONID
		setupPOSTConnection(urlString, logonString.length());
		
		// post the login query
		// Username, Password
		PrintWriter out = new PrintWriter(conn.getOutputStream());
		out.write(logonString);
		out.flush();
		out.close();
		
		//Important: to ignore response so that the connection can be recylcled.
		conn.getInputStream().close();
	}
	
	private NodeList retrieve() throws Exception{
		//https://law5.law.virginia.edu/apptrack/s/myappinfo.jsp
		urlString = conn.getHeaderField("Location");
		
		//if retrieval failed
		if(urlString == null) {
			return null;
		}
		
		setupGETConnection(urlString);
		
		parser = new Parser(conn);
		NodeList nodes = parser.parse(
				new HasSiblingFilter(
					new HasChildFilter(
							new StringFilter("Application Complete?")
					)
				)
		);
		
		//JSESSIONIDSSO
		receiveCookies();
		
		return nodes;
	}
	
	private void logoff() throws Exception {
		urlString = "https://law5.law.virginia.edu/apptrack/s/myappinfo.jsp?logoff=true";
		setupGETConnection(urlString);
		conn.connect();
		conn.getInputStream().close();
	}
	
	/**
	 * Virginia Law StatusChecker Logic (AdmitWeb)
	 */
	public String getStatusMessage(String username, String password) {
		//loosely sanitize username and password
		if(!Validation.isGeneralLoginWellFormed(username, password)) {
			statusCode = AUTH_FAIL;
			return null;
		}
		
		//get jsessionid, path
		connectForCookies();
		
		NodeList nodes = null;
		try {
			logon(username, password);
			
			nodes = retrieve();
			
			if(nodes == null || nodes.size() != 5) {
				statusCode = AUTH_FAIL;
				return null;
			} else {
				statusCode = SUCCESS;
				logoff();//confirmed to work
				
				StringBuilder responseString = new StringBuilder();
				responseString.append(nodes.elementAt(3).toPlainTextString().substring(0, WORD_LIMIT));
				responseString.append("...");
				return responseString.toString();
			}
		} catch (Exception e) {
			statusCode = ERR;
			e.printStackTrace();
			return null;
		}
	}

}
